#include <gtest/gtest.h>
#include "FloatUtils.h"

const double TOLERANCE = 0.000001;

TEST(FloatUtils, square)
{
    EXPECT_NEAR(100.0,  FloatUtils::square( 10.0), TOLERANCE);
    EXPECT_NEAR(100.0,  FloatUtils::square(-10.0), TOLERANCE);
    EXPECT_NEAR(  0.01, FloatUtils::square(  0.1), TOLERANCE);
    EXPECT_NEAR(  0.01, FloatUtils::square( -0.1), TOLERANCE);
}

TEST(FloatUtils, third)
{
    EXPECT_NEAR( 1000.0,   FloatUtils::third( 10.0), TOLERANCE);
    EXPECT_NEAR(-1000.0,   FloatUtils::third(-10.0), TOLERANCE);
    EXPECT_NEAR(    0.001, FloatUtils::third(  0.1), TOLERANCE);
    EXPECT_NEAR(   -0.001, FloatUtils::third( -0.1), TOLERANCE);
}

TEST(FloatUtils, sign)
{
    EXPECT_NEAR( 10.0, FloatUtils::sign( 10.0,  10.0), TOLERANCE);
    EXPECT_NEAR( 10.0, FloatUtils::sign(-10.0,  10.0), TOLERANCE);
    EXPECT_NEAR(-10.0, FloatUtils::sign( 10.0, -10.0), TOLERANCE);
    EXPECT_NEAR(-10.0, FloatUtils::sign(-10.0, -10.0), TOLERANCE);
}

TEST(FloatUtils, power)
{
    EXPECT_NEAR(    0.0,  FloatUtils::power(  0.0,  0.0), TOLERANCE);
    EXPECT_NEAR(    0.0,  FloatUtils::power(  0.0,  2.0), TOLERANCE);
    EXPECT_NEAR(    0.0,  FloatUtils::power(  0.0, -2.0), TOLERANCE);
    EXPECT_NEAR(    0.0,  FloatUtils::power(  0.0,  0.5), TOLERANCE);
    EXPECT_NEAR(    0.0,  FloatUtils::power(  0.0, -0.5), TOLERANCE);
    EXPECT_NEAR(    0.0,  FloatUtils::power(  0.0,  3.0), TOLERANCE);
    EXPECT_NEAR(    1.0,  FloatUtils::power( 10.0,  0.0), TOLERANCE);
    EXPECT_NEAR(   10.0,  FloatUtils::power( 10.0,  1.0), TOLERANCE);
    EXPECT_NEAR(  100.0,  FloatUtils::power( 10.0,  2.0), TOLERANCE);
    EXPECT_NEAR(    0.1,  FloatUtils::power( 10.0, -1.0), TOLERANCE);
    EXPECT_NEAR(    0.01, FloatUtils::power( 10.0, -2.0), TOLERANCE);
    EXPECT_NEAR( 1000.0,  FloatUtils::power( 10.0,  3.0), TOLERANCE);
    EXPECT_NEAR(    1.0,  FloatUtils::power(-10.0,  0.0), TOLERANCE);
    EXPECT_NEAR(  -10.0,  FloatUtils::power(-10.0,  1.0), TOLERANCE);
    EXPECT_NEAR(  100.0,  FloatUtils::power(-10.0,  2.0), TOLERANCE);
    EXPECT_NEAR(   -0.1,  FloatUtils::power(-10.0, -1.0), TOLERANCE);
    EXPECT_NEAR(    0.01, FloatUtils::power(-10.0, -2.0), TOLERANCE);
    EXPECT_NEAR(-1000.0,  FloatUtils::power(-10.0,  3.0), TOLERANCE);
}

TEST(FloatUtils, modulo)
{
    EXPECT_EQ( 3, FloatUtils::modulo( 8, 5));
    EXPECT_EQ( 2, FloatUtils::modulo(-8, 5));
    EXPECT_EQ(-2, FloatUtils::modulo( 8,-5));
    EXPECT_EQ(-3, FloatUtils::modulo(-8,-5));
}

TEST(FloatUtils, randomNumber)
{
    {
        float r1 = FloatUtils::randomNumber(false);
        float r2 = FloatUtils::randomNumber(false);
        EXPECT_NE(r1, r2); // not guaranteed!
    }
    {
        float r1 = FloatUtils::randomNumber(true);
        float r2 = FloatUtils::randomNumber(true);
        EXPECT_NE(r1, r2); // not guaranteed!
    }
}

